﻿Imports Aricie.DNN.Services.Filtering
Imports System.Linq

Namespace Aricie.DNN.Services.Url.FriendlyUrl

    Public Class UrlRewriteContext

        Public Sub New(ByVal rewriteInput As UrlRewriteInput)
            Me._RewriteInput = rewriteInput
        End Sub

        Private _ParamsUsage As New Dictionary(Of UrlParam, ParamState)
        Private _GroupRewrites As New Dictionary(Of UrlGroup, GroupRewriteResult)
        Private _RewriteInput As UrlRewriteInput


        Public Property ParamsUsage(ByVal objUrlParam As UrlParam) As ParamState
            Get
                Dim toReturn As ParamState = Nothing
                If Me._ParamsUsage.TryGetValue(objUrlParam, toReturn) Then
                    Return toReturn
                End If
                Return ParamState.Untouched
            End Get
            Set(ByVal value As ParamState)
                Me._ParamsUsage(objUrlParam) = value
            End Set
        End Property

        Public Sub RegisterRewrite(ByVal group As UrlGroup, ByVal result As GroupRewriteResult)
            If Me._GroupRewrites.ContainsKey(group) Then
                Throw New ApplicationException("Group already processed")
            End If
            Me.GroupRewrites(group) = result
        End Sub

        Public ReadOnly Property RewriteInput() As UrlRewriteInput
            Get
                Return _RewriteInput
            End Get
        End Property

        Public ReadOnly Property GroupRewrites() As Dictionary(Of UrlGroup, GroupRewriteResult)
            Get
                Return _GroupRewrites
            End Get
        End Property


        Public Function GetRewriteValue(result As GroupRewriteResult, objUrlGroup As UrlGroup) As String
            If result.HasContent Then
                Dim filter As ExpressionFilterInfo = Nothing
                If objUrlGroup.EnableFilter Then
                    filter = objUrlGroup.ExpressionFilter
                End If
                Dim atr As AdvancedTokenReplace = Nothing
                If objUrlGroup.EnableTokenReplace Then
                    atr = objUrlGroup.GetAdvancedTokenReplace(Me._RewriteInput)
                    If result.RewriteEntity IsNot Nothing AndAlso Not String.IsNullOrEmpty(objUrlGroup.EntityToken) Then
                        atr.SetObjectReplace(result.RewriteEntity, "RewriteEntity")
                        Dim strToken As String = String.Format("[RewriteEntity:{0}]", objUrlGroup.EntityToken)
                        Return GetRewriteValueInternal(strToken, atr, filter)
                    End If
                End If

                Dim toReturnBuilder As New StringBuilder
                Dim isFirstPass As Boolean = True

                For Each objValuePair As KeyValuePair(Of String, String) In result.RewriteValues


                    If isFirstPass Then
                        isFirstPass = False
                    Else
                        toReturnBuilder.Append(objUrlGroup.GetSeparationChar)
                    End If
                    If String.IsNullOrEmpty(objValuePair.Key) Then
                        toReturnBuilder.Append(GetRewriteValueInternal(objValuePair.Value, atr, filter))
                    Else
                        toReturnBuilder.Append(GetRewriteValueInternal(objValuePair.Key, atr, filter))
                        toReturnBuilder.Append(objUrlGroup.GetParamValueChar)
                        toReturnBuilder.Append(GetRewriteValueInternal(objValuePair.Value, atr, filter))
                    End If
                Next
                Return toReturnBuilder.ToString
            End If

            Return String.Empty
        End Function


        Private Function GetRewriteValueInternal(singleValue As String, atr As AdvancedTokenReplace, filter As ExpressionFilterInfo) As String
            If atr IsNot Nothing Then
                singleValue = atr.ReplaceAllTokens(singleValue)
            End If
            If filter IsNot Nothing Then
                singleValue = filter.Process(singleValue)
            End If
            Return singleValue
        End Function

    End Class

End Namespace
